import React, { useEffect, useRef, useState } from "react";
import lessModule from "./index.module.less"
import { Button, Empty, Modal, Radio, RadioChangeEvent, Select, Space, Table, Upload } from "antd";
import Dragger from "antd/es/upload/Dragger";
import emptyImage from "../../../../assets/image//homePageReasoningPage-tableEmpty.png"
import featherImage from "../../../../assets/image/homePageReasoningPage-modalFeather.png"
import infoImage from "../../../../assets/image/homePageReasoningPage-modalInfo.png"
import { $labelDictInterface } from "../../../../common/type";
import { $Http } from "../../../../network";
import HomePage_ChartScatterComponent from "../../component/chartScatter";

// 主页_单次推理页面
const HomePage_ReasoningPage = () => {
    // 单选框子项类型约束
    interface radioItemInterface {
        label: string
        dataLabel: string
        fileLabel: string
        fileAcceptList: Array<string>
    }
    // 页面dom
    const pageRef = useRef<HTMLDivElement>(null)
    // 推理模型列表
    const [reasoningModelList, setReasoningModelList] = useState<Array<$labelDictInterface>>([])
    // 选中的推理模型
    let [modelName, setModelName] = useState<string | null>(null)
    // 单选框列表
    const radioList: Array<radioItemInterface> = [
        {
            label: "图片",
            dataLabel: "图片",
            fileLabel: "图片",
            fileAcceptList: [".JPG", ".PNG"],

        },
        {
            label: "Excel数据",
            dataLabel: "Excel数据",
            fileLabel: "Excel文件",
            fileAcceptList: [".XLS", ".XLSX", ".CSV"],
        },
    ]
    // 单选框选中值
    const [radioSelectedDict, setRadioSelectedDict] = useState<radioItemInterface>(radioList[0])
    // 文件名
    const [fileName, setFileName] = useState<string>("")
    // 拖拽是否错误
    let [isDropErr, setIsDropErr] = useState<boolean>(false)
    // 文件
    let [file, setFile] = useState<File | null>(null)
    // 表格表头列表
    const tableColumnList: Array<object> = [
        {
            title: '异常类型',
            dataIndex: "type",
            render: (text: string) => text ?? "-/-",
        },
        {
            title: '概率',
            dataIndex: "probability",
            width: 120,
            render: (text: string) => text ?? "-/-",
        },
    ]
    // 表格纵向滚动区域高度
    let [tableScrollH, setTableScrollH] = useState<number>(0)
    // 是否上传完成
    const [isUploadCompleted, setIsUploadCompleted] = useState<boolean>(false)
    // 表格数据源
    const [tableSourceList, setTableSourceList] = useState<Array<object>>([])
    // 结果
    const [result, setResult] = useState<string>("")
    // 功率
    const [chartSourceList, setChartSourceList] = useState<Array<Array<number>>>([])

    /**
     * @brief 监听模型名称
     * @param value:string 选中的模型名称
     * @return 
     * @note 
     * @warning 
     */
    const change_modelName = (value: string) => {
        modelName = value
        setModelName(modelName)
        make_bodyDomH()
        http_processInference()
    }
    /**
     * @brief 监听单选框
     * @param event: RadioChangeEvent 操作的数据
     * @return 
     * @note 
     * @warning 
     */
    const change_radio = (event: RadioChangeEvent) => {
        setRadioSelectedDict({ ...radioList.filter((item: radioItemInterface) => item.label === event.target.value)[0] })
        setIsDropErr(false)
        setFileName("")
        setTableSourceList([])
        setResult("")
        setIsUploadCompleted(false)
    }
    /**
     * @brief 监听单选框
     * @param event: RadioChangeEvent 操作的数据
     * @return 
     * @note 
     * @warning 
     */
    const change_drop = (event: React.DragEvent) => {
        isDropErr = !radioSelectedDict.fileAcceptList.includes(`.${event.dataTransfer.files[0].name.split(".").slice(-1)}`.toUpperCase())
        setIsDropErr(isDropErr)
        if (!isDropErr) {
            file = event.dataTransfer.files[0]
            setFile(file)
            http_processInference()
            setFileName(event.dataTransfer.files[0].name)
        }
    }

    /**
     * @brief 拖拽或上传文件
     * @param event: any 操作的数据
     * @return 返回值说明
     * @note 可选注意事项
     * @warning 可选警告信息
     */
    const change_upload = (event: any) => {
        file = event.file
        setFile(event.file)
        http_processInference()
        setFileName(event.file.name)
    }
    /**
     * @brief 表格
     * @param 参数说明
     * @return 返回值说明
     * @note 可选注意事项
     * @warning 可选警告信息
         */
    const className_tableRow = (record: object, idx: number) => {
        return result.split(",").includes(record['type']) ? `${lessModule["main-result__tableRow"]}` : ""
    }
    /**
     * @brief 生成表格主体高度
     * @param 
     * @return 
     * @note 
     * @warning 
     */
    const make_bodyDomH = () => {
        setTimeout(() => {
            const bodyDom = document.querySelector('.ant-table-body') as HTMLElement
            bodyDom.style.height = `${tableScrollH}px`
        });
    }
    /**
     * @brief 获取表格纵向滚动区域高度
     * @param 
     * @return 
     * @note 
     * @warning 
    */
    const eventListener_windowResize = () => {
        if (pageRef.current) {
            // 页面高度 - 头部高度 - 单选框高度 - 单选框下外边距 - 主体上下外边距 - 主体上下边框 - 主体上下内边距 - 说明文字高度 - 占位文字高度 - 拖曳上传高度 - 上传按钮高度 - 检测结果高度 - 主体内间隔 * 6 - 表格表头高度  - 表格上下边框 - 底部高度
            tableScrollH = pageRef.current.clientHeight - 33 - 12 * 2 - 1 * 2 - 32 * 2 - 25.14 - 8 - 20 - 20 - 160 - (isDropErr ? 20 : 0) - 32 - 24 - 16 * 6 - 58.14 - 2 - 20
            setTableScrollH(tableScrollH)
            modelName && make_bodyDomH()
        }
    }


    /**
     * @brief 获取推理模型
     * @param 
     * @return 
     * @note 
     * @warning 
     */
    const http_inference = () => {
        $Http("inference", {}).then((res: object) => {
            setReasoningModelList([...res["model_list"]])
            modelName = res["model_list"][0].label ?? ""
            setModelName(modelName)
            make_bodyDomH()
        })
    }
    /**
     * @brief 处理推理
     * @param 
     * @return 
     * @note 
     * @warning 
     */
    const http_processInference = () => {
        setIsUploadCompleted(false)
        if (file) {
            const formData = new FormData();
            formData.append('model_name', modelName ?? "");
            // 将File对象添加到FormData中
            formData.append('files', file);
            setTableSourceList([])
            setResult("")
            $Http("processInference", formData, "post", "file").then((res: object) => {
                setTableSourceList([...res["details"]])
                setResult(res["result"])
                if (radioSelectedDict.fileLabel === "Excel文件") {
                    setChartSourceList([...res["value"]])
                }
                setIsUploadCompleted(true)
            })
        }
    }

    useEffect(() => {
        http_inference()
        eventListener_windowResize()
        // 表格纵向滚动区域高度监听器（监听浏览器页面的变化）
        window.addEventListener('resize', eventListener_windowResize);
        return () => {
            // 清除监听器
            window.removeEventListener('resize', eventListener_windowResize)
        };
    }, [])
    return (
        <div ref={pageRef} className={lessModule["homePageReasoningPage"]} >
            <header className={lessModule["homePageReasoningPage-header"]}>
                <span>选择推理模型(.onnx)：</span>
                <Select className={lessModule["homePageReasoningPage-header__select"]} placeholder="请选择" value={modelName} options={reasoningModelList} fieldNames={{ value: "label" }} onChange={change_modelName} />
            </header>
            {
                modelName && <main className={lessModule["homePageReasoningPage-main"]}>
                    <div className={lessModule["homePageReasoningPage-main__radioGroup"]}>
                        {
                            radioList.map((item: radioItemInterface, idx: number) => (
                                <Radio key={`radioList_item_${idx}`} value={item.label} checked={radioSelectedDict.label === item.label} onChange={change_radio}>
                                    <span
                                    // style={{ color: radioSelectedDict.label === item.label ? "#17A1E6" : "#ffffff" }}
                                    >使用{item.label}分类</span>
                                </Radio>
                            ))
                        }
                    </div>
                    <span>请拖拽{radioSelectedDict.fileLabel}到下方区域或点击按钮选择{radioSelectedDict.fileLabel}</span>
                    <div className={lessModule["homePageReasoningPage-main__placeholder"]}>
                        <span>{fileName ? `当前${radioSelectedDict.fileLabel}：${fileName}` : "未选择文件"}</span>
                        <span>{fileName ? isUploadCompleted ? `处理完成：${fileName}` : "正在处理，请稍后..." : "请选择文件进行分析"}</span>
                    </div>
                    <div className={lessModule["homePageReasoningPage-main__dragger"]}>
                        <Dragger action='https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload' accept={radioSelectedDict.fileAcceptList.join(",")} openFileDialogOnClick={false} beforeUpload={() => false} onDrop={change_drop}>
                            <span>将{radioSelectedDict.dataLabel}拖拽到此处（仅支持 {radioSelectedDict.fileAcceptList.join("、")}）</span>
                        </Dragger>
                        {
                            isDropErr && <span>拖曳的文件类型不匹配！</span>
                        }
                    </div>
                    <Upload accept={radioSelectedDict.fileAcceptList.join(",")} beforeUpload={() => false} onChange={change_upload}>
                        <Button type="primary">选择{radioSelectedDict.fileLabel}</Button>
                    </Upload>
                    <div className={lessModule["homePageReasoningPage-main__result"]}>
                        <div className={lessModule["main-result__preview"]}>
                            <span>输入图像预览</span>
                            {
                                file && isUploadCompleted && (radioSelectedDict.fileLabel === "图片" ? <img className={lessModule["result-preview__content"]} src={URL.createObjectURL(file)} />
                                    : <HomePage_ChartScatterComponent sourceList={chartSourceList} />)
                            }

                        </div>
                        <Table rowKey={(record, idx) => "homePageReasoningPageTable" + idx} scroll={{ y:tableScrollH }} pagination={false} rowClassName={className_tableRow} columns={tableColumnList} dataSource={tableSourceList}
                            locale={{
                                emptyText: <Empty image={emptyImage} imageStyle={{
                                    width: 120,
                                    height: 120,
                                    marginTop: (tableScrollH - 150) / 2,
                                }} />

                            }} />
                    </div>
                    <span className={lessModule["homePageReasoningPage-main__testReasult"]}>
                        <span>检测结果：</span>
                        <span className={lessModule["main-result__value"]}>{result ? result : "N/A"}</span>
                    </span>
                </main>
            }
            <footer className={lessModule["homePageReasoningPage-footer"]}> {modelName ? `已加载模型: ${modelName}。请提供文件进行推理。` : "请选择要加载的模型！"}</footer>
        </div>
    )

}

export default HomePage_ReasoningPage